package gruppe5.dame.client.loginDialog;

import gruppe5.dame.client.Hauptfenster;

import java.awt.Color;
import java.awt.GridLayout;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;

/**
 * Der LoginDialog ermöglicht die Eingabe von Ip-Adresse und Benutzername.
 * @author Martin Eutinger
 *
 */
public class LoginDialog extends JDialog
{

	/**
	 * generated serial version ID
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Regul�rer Ausdruck zum Pr�fen der IP Adresse.
	 * Quelle: http://www.mkyong.com/regular-expressions/how-to-validate-ip-address-with-regular-expression/.
	 */
	private static final String IP_PATTERN = 
	        "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
	        "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
	        "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
	        "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
	
	/**
	 * Regul�rer Ausdruck zum Pr�fen des Benutzernames.
	 * Quelle: http://net.tutsplus.com/tutorials/other/8-regular-expressions-you-should-know/.
	 */
	private static final String USERNAME_PATTERN = "^[A-Za-z0-9_-]{3,10}$";
	
	/**
	 * Das Textfeld zur Eingabe der IP-Adresse.
	 */
	private JFormattedTextField ipTextField = null;
	
	/**
	 * Das Textfeld zur Eingabe des Benutzernames.
	 */
	private JFormattedTextField nameTextField = null;
	
	/**
	 * Der zum Abschicken der eingegebenen Benutzerdaten.
	 * Er wird erst aktiviert wenn korrekte Benutzerdaten eingegeben wurden.
	 */
	private JButton connectButton = null;
	
	/**
	 * Logindaten werden gespeichert wenn diese Box getickt wurde.
	 */
	private JCheckBox saveLoginBox;

	private String ip = "";

	private String username = "";
	
	/**
	 * Hauptfenster
	 */
	private static Hauptfenster frame;
	
	/**
	 * Standardkonstruktor des LoginDialogs.
	 * Wird aufgerufen wenn noch keine Eingabedaten bekannt sind.
	 * Stellt den LoginDialog so ein, dass er immer im Vordergrund bleibt,
	 * nicht geschlossen werden kann,
	 * nicht in der Gr��e �nderbar ist.
	 * Erzeugt die Elemente die der LoginDialog besitzt.
	 */
	public LoginDialog(Hauptfenster frame)
	{
		this.frame = frame;
		this.setTitle("Verbindungsdaten eingeben");
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		this.setResizable(false);
		this.setAlwaysOnTop(true);
		this.setFocusable(true);
		
		this.setLayout(new GridLayout(4, 2));
		
		
		ListenerLoginDialogButton listenerLoginDialogButton = new ListenerLoginDialogButton(this);
		ListenerLoginDialogTextField listenerLoginDialogTextField = new ListenerLoginDialogTextField(this);
		
		/**
		 * Erzeugung aller Komponenten des LoginDialogs, Anfang.
		 */
		//IP ADRESSE
		JLabel ipLabel = new JLabel("Connect to IP");
		this.add(ipLabel);
		
		this.ipTextField = new JFormattedTextField();
		this.ipTextField.getDocument().addDocumentListener(listenerLoginDialogTextField);
		this.add(ipTextField);
		
		
		//BENUTZERNAME
		JLabel username = new JLabel("Username");
		this.add(username);
		
		this.nameTextField = new JFormattedTextField();
		this.nameTextField.getDocument().addDocumentListener(listenerLoginDialogTextField);
		this.add(nameTextField);
	
		
		//CHECKBOX
		this.add(new JLabel("Logindaten speichern"));
		saveLoginBox = new JCheckBox();
		saveLoginBox.setActionCommand("Checkbox");
		saveLoginBox.addActionListener(listenerLoginDialogButton);
		this.add(saveLoginBox);
		
		
		//VERBINDEN BUTTON
		this.connectButton = new JButton("Connect");
		this.connectButton.addActionListener(listenerLoginDialogButton);
		this.connectButton.setEnabled(false);
		this.add(connectButton);
		
		//RESET BUTTON
		JButton resetButton = new JButton("Reset");
		resetButton.addActionListener(listenerLoginDialogButton);
		this.add(resetButton);
		
		/**
		 * Erzeugung aller Komponenten des LoginDialogs, Ende.
		 */
		
		
		this.pack();
		this.setVisible(true);
		this.ipTextField.grabFocus(); //Gibt dem obersten Textfeld den Focus.
	}
	
	/**
	 * Konstruktor des LoginDialogs.
	 * Wird aufgerufen wenn die IP-Adresse bereits bekannt ist (z.B. bei
	 * falschem Name, aber richtiger IP). Die IP wird als default-Wert eingetragen.
	 * @param _ipAddress Die IP-Adresse als voreingetragener Wert.
	 */
	public LoginDialog(Hauptfenster frame, String _ipAddress)
	{
		this(frame);
		this.ipTextField.setForeground(Color.gray);
		this.ipTextField.setText(_ipAddress);
		this.nameTextField.grabFocus(); //IP ist bereits eingetragen -> Namenseingabe kriegt den Focus.
	}
	
	/**
	 * Konstruktor des LoginDialogs.
	 * Wird aufgerufen wenn IP-Adresse und Username bereits bekannt sind 
	 * (z.B. wenn Voreinstellungen aus einer Datei gelesen werden, weil die 
	 * Checkbox getickt wurden). IP und Username werden als default-Werte eingetragen.
	 * @param _ipAddress Die IP-Adresse als voreingetragener Wert.
	 * @param _username Der Username als voreingetragener Wert.
	 */
	public LoginDialog(Hauptfenster frame, String _ipAddress, String _username)
	{
		this(frame);
		this.ipTextField.setForeground(Color.gray);
		this.ipTextField.setText(_ipAddress);
		this.nameTextField.setForeground(Color.gray);
		this.nameTextField.setText(_username);
		this.connectButton.grabFocus(); //Beide Werte bereits eingetragen -> Connect-Button kriegt den Focus.
	}
	

	/**
	 * Update des Connect-Buttons.
	 * Wird auf enabled gesetzt, falls Ip-Adresse und Username
	 * korrekt eingegeben wurden.
	 */
	public void updateDialog()
	{
		this.ipTextField.setForeground(Color.black);
		this.nameTextField.setForeground(Color.black);
		
		boolean ipAddressValidity = this.isValidIpAddress(this.getIp());
		boolean usernameValidity = this.isValidUsername(this.getUsername());
		if(ipAddressValidity && usernameValidity)
		{
			this.setButtonEnabled(true);
		} else {
			this.setButtonEnabled(false);
		}
	}
	
	/**
	 * Pr�ft ob die Ip-Adresse ipAddress der richtigen 
	 * Ipv4 Form (IP_PATTERN) entspricht.
	 * @param ipAddress Die zu pr�fende Ip-Adresse.
	 * @return true wenn die Ip-Adresse korrekt ist.
	 */
	private boolean isValidIpAddress(String ipAddress)
	{
		Pattern ipRegEx = Pattern.compile(IP_PATTERN);
		Matcher matcher = ipRegEx.matcher(ipAddress);
		return matcher.matches();
	}
	


	/**
	 * Pr�ft ob der Username username der richtigen 
	 * Form (USERNAME_PATTERN) entspricht.
	 * @param username Der zu pr�fende Username-Adresse.
	 * @return true wenn Username korrekt ist.
	 */
	private boolean isValidUsername(String username) 
	{
		Pattern usernameRegEx = Pattern.compile(USERNAME_PATTERN);
		Matcher matcher = usernameRegEx.matcher(username);
		return matcher.matches();
	}
	
	/**
	 * Liefert die Ip-Adresse die ins Textfeld eingetragen wurde.
	 * @return Die Ip-Adresse die ins Textfeld eingetragen wurde.
	 */
	public String getIp() { return ipTextField.getText(); }
	
	/**
	 * Liefert den Usernamen, der ins Textfeld eingetragen wurde.
	 * @return Der Usernamen, der ins Textfeld eingetragen wurde.
	 */
	public String getUsername() { return nameTextField.getText(); }
	
	/**
	 * Setzt den Connect-Button auf buttonState.
	 * @param buttonState True wenn auf Enabled gesetzt werden soll.
	 */
	private void setButtonEnabled(boolean buttonState)
	{
		this.connectButton.setEnabled(buttonState);
	}
	
	/**
	 * L�scht alle Texteingaben.
	 * Ausl�sung wahrscheinlich durch Reset-Button.
	 */
	public void resetText()
	{
		this.ipTextField.setText(null);
		this.nameTextField.setText(null);
		this.connectButton.setEnabled(false);
	}

	/**
	 * Login &uumlber die Netzwerkkommunikation des Hauptfensters
	 * @param ip
	 * @param username
	 */
	public void login(String ip, String username) {
		frame.login(ip, username);
	}

	/**
	 * Bei erfolgreicher Verbindung Daten speichern
	 */
	public void saveConnectionData() {
		frame.saveConnectionData(true);
	}

	
	public void loginData(String ip, String username) {
		ipTextField.setText(ip);
		nameTextField.setText(username);
		this.ipTextField.setForeground(Color.gray);
		this.nameTextField.setForeground(Color.gray);
		this.saveLoginBox.setSelected(true);
	}
}